// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SerializedAttributesImpl.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           This file contains various implementations of the
//                  SerializedAttribute class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "SerializedAttributesImpl.h"


// SerializedAabbox3d class
// SerializedAabbox3d constructor (aabbox3di).
SerializedAabbox3d::SerializedAabbox3d(const std::string &name, const aabbox3di &value)
: SerializedAttribute(name, "aabbox3d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedAabbox3d constructor (aabbox3df).
SerializedAabbox3d::SerializedAabbox3d(const std::string &name, const aabbox3df &value)
: SerializedAttribute(name, "aabbox3d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedAabbox3d deconstructor.
SerializedAabbox3d::~SerializedAabbox3d()
{
}

aabbox3df SerializedAabbox3d::getAabbox3df()
{
    return convert<f32, f64>(mValue);
}

aabbox3di SerializedAabbox3d::getAabbox3di()
{
    return convert<s32, f64>(mValue);
}

std::string SerializedAabbox3d::getString()
{
    SerializedVector3d MaxEdge("", mValue.MaxEdge);
    SerializedVector3d MinEdge("", mValue.MinEdge);

    stringstream ss;
    ss << "aabbox3d(" << MinEdge.getString() << ", " << MaxEdge.getString() << ")";

    return ss.str();
}

void SerializedAabbox3d::setAabbox3df(const aabbox3df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedAabbox3d::setAabbox3di(const aabbox3di &value)
{
    mValue = convert<f64, s32>(value);
}

void SerializedAabbox3d::setString(const std::string &value)
{
    std::string typelessValue = removeStringFormatting(value, "aabbox3d");

    SerializedVector3d MinEdge("", vector3df());
    MinEdge.setString(typelessValue.substr(0, typelessValue.find(")")+1));

    SerializedVector3d MaxEdge("", vector3df());
    MaxEdge.setString(typelessValue.substr(typelessValue.find(")")+1));

    aabbox3df aabbox;
    aabbox.MinEdge = MinEdge.getVector3df();
    aabbox.MaxEdge = MaxEdge.getVector3df();

    mValue = convert<f64, f32>(aabbox);
}


// SerializedBool class
// SerializedBool constructor.
SerializedBool::SerializedBool(const std::string &name, bool value)
: SerializedAttribute(name, "bool")
{
    mValue = value;
}

// SerializedBool deconstructor.
SerializedBool::~SerializedBool()
{
}

// Reimplementations of superclass' methods.
bool SerializedBool::getBool()
{
    return mValue;
}

f32 SerializedBool::getFloat()
{
    return (mValue) ? 1.0f : 0.0f;
}

s32 SerializedBool::getInt()
{
    return (mValue) ? 1 : 0;
}

std::string SerializedBool::getString()
{
    return (mValue) ? "true" : "false";
}

void SerializedBool::setBool(bool value)
{
    mValue = value;
}

void SerializedBool::setFloat(f32 value)
{
    mValue = (value != 0.0f);
}

void SerializedBool::setInt(s32 value)
{
    mValue = (value != 0);
}

void SerializedBool::setString(const std::string &value)
{
    mValue = (value == "true");
}


// SerializedColor class
// SerializedColor constructor.
SerializedColor::SerializedColor(const std::string &name, const SColorf &value)
: SerializedAttribute(name, "color")
{
    mValue = value;
}

// SerializedColor deconstructor.
SerializedColor::~SerializedColor()
{
}

// Reimplementations of superclass' methods.
SColor SerializedColor::getColor()
{
    return mValue.toSColor();
}

SColorf SerializedColor::getColorf()
{
    return mValue;
}

f32 SerializedColor::getFloat()
{
    return (f32)mValue.toSColor().color;
}

s32 SerializedColor::getInt()
{
    return (s32)mValue.toSColor().color;
}

std::string SerializedColor::getString()
{
    stringstream ss;
    ss << "color(" << mValue.getAlpha() << ", " << mValue.getRed() << ", "
                   << mValue.getGreen() << ", " << mValue.getBlue() << ")";

    return ss.str();
}

void SerializedColor::setColor(const SColor &value)
{
    mValue = value;
}

void SerializedColor::setColorf(const SColorf &value)
{
    mValue = value;
}

void SerializedColor::setFloat(f32 value)
{
    setInt((s32)value);
}

void SerializedColor::setInt(s32 value)
{
    mValue = SColor(value);
}

void SerializedColor::setString(const std::string &value)
{
    // Remove formatting from the given string.
    stringstream ss(removeStringFormatting(value, "color"));

    // Set the new values of the color.
    ss >> mValue.a;
    ss >> mValue.r;
    ss >> mValue.g;
    ss >> mValue.b;
}


// SerializedDimension2d class
// SerializedDimension2d constructor (dimension2df).
SerializedDimension2d::SerializedDimension2d(const std::string &name, const dimension2df &value)
: SerializedAttribute(name, "dimension2d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedDimension2d constructor (dimension2di).
SerializedDimension2d::SerializedDimension2d(const std::string &name, const dimension2di &value)
: SerializedAttribute(name, "dimension2d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedDimension2d deconstructor.
SerializedDimension2d::~SerializedDimension2d()
{
}

std::string SerializedDimension2d::getString()
{
    stringstream ss;
    ss << "dimension2d(" << mValue.Width << ", " << mValue.Height << ")";

    return ss.str();
}

dimension2df SerializedDimension2d::getDimension2df()
{
    return convert<f32, f64>(mValue);
}

dimension2di SerializedDimension2d::getDimension2di()
{
    return convert<s32, f64>(mValue);
}

void SerializedDimension2d::setDimension2df(const dimension2df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedDimension2d::setDimension2di(const dimension2di &value)
{
    mValue = convert<f64, s32>(value);
}

void SerializedDimension2d::setString(const std::string &value)
{
    // Remove formatting from the given string.
    stringstream ss(removeStringFormatting(value, "dimension2d"));

    // Set the new values of the dimension2d.
    ss >> mValue.Width;
    ss >> mValue.Height;
}


// SerializedLine2d class
// SerializedLine2d constructor (line2df).
SerializedLine2d::SerializedLine2d(const std::string &name, const line2df &value)
: SerializedAttribute(name, "line2d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedLine2d constructor (line2di).
SerializedLine2d::SerializedLine2d(const std::string &name, const line2di &value)
: SerializedAttribute(name, "line2d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedLine2d deconstructor.
SerializedLine2d::~SerializedLine2d()
{
}

std::string SerializedLine2d::getString()
{
    SerializedVector2d start("", mValue.start);
    SerializedVector2d end("", mValue.end);

    stringstream ss;
    ss << "line2d(" << start.getString() << ", " << end.getString() << ")";

    return ss.str();
}

line2df SerializedLine2d::getLine2df()
{
    return convert<f32, f64>(mValue);
}

line2di SerializedLine2d::getLine2di()
{
    return convert<s32, f64>(mValue);
}

void SerializedLine2d::setLine2df(const line2df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedLine2d::setLine2di(const line2di &value)
{
    mValue = convert<f64, s32>(value);
}

void SerializedLine2d::setString(const std::string &value)
{
    std::string typelessValue = removeStringFormatting(value, "line2d");

    SerializedVector2d start("", vector2df());
    start.setString(typelessValue.substr(0, typelessValue.find(")")+1));

    SerializedVector2d end("", vector2df());
    end.setString(typelessValue.substr(typelessValue.find(")")+1));

    line2df line;
    line.start = start.getVector2df();
    line.end = end.getVector2df();

    mValue = convert<f64, f32>(line);
}

// SerializedLine3d class
// SerializedLine3d constructor (line3df).
SerializedLine3d::SerializedLine3d(const std::string &name, const line3df &value)
: SerializedAttribute(name, "line3d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedLine3d constructor (line3di).
SerializedLine3d::SerializedLine3d(const std::string &name, const line3di &value)
: SerializedAttribute(name, "line3d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedLine3d deconstructor.
SerializedLine3d::~SerializedLine3d()
{
}

std::string SerializedLine3d::getString()
{
    SerializedVector3d start("", mValue.start);
    SerializedVector3d end("", mValue.end);

    stringstream ss;
    ss << "line3d(" << start.getString() << ", " << end.getString() << ")";

    return ss.str();
}

line3df SerializedLine3d::getLine3df()
{
    return convert<f32, f64>(mValue);
}

line3di SerializedLine3d::getLine3di()
{
    return convert<s32, f64>(mValue);
}

void SerializedLine3d::setLine3df(const line3df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedLine3d::setLine3di(const line3di &value)
{
    mValue = convert<f64, s32>(value);
}

void SerializedLine3d::setString(const std::string &value)
{
    std::string typelessValue = removeStringFormatting(value, "line3d");

    SerializedVector3d start("", vector3df());
    start.setString(typelessValue.substr(0, typelessValue.find(")")+1));

    SerializedVector3d end("", vector3df());
    end.setString(typelessValue.substr(typelessValue.find(")")+1));

    line3df line;
    line.start = start.getVector3df();
    line.end = end.getVector3df();

    mValue = convert<f64, f32>(line);
}

// SerializedNumber class
// SerializedNumber constructor.
SerializedNumber::SerializedNumber(const std::string &name, s32 value)
: SerializedAttribute(name, "number")
{
    mValue = (f64)value;
}

// SerializedNumber constructor.
SerializedNumber::SerializedNumber(const std::string &name, f32 value)
: SerializedAttribute(name, "number")
{
    mValue = (f64)value;
}

// SerializedNumber deconstructor.
SerializedNumber::~SerializedNumber()
{
}

// Reimplementations of superclass' methods.
bool SerializedNumber::getBool()
{
    return (mValue != 0.0f);
}

f32 SerializedNumber::getFloat()
{
    return (f32)mValue;
}

s32 SerializedNumber::getInt()
{
    return (s32)mValue;
}

std::string SerializedNumber::getString()
{
    stringstream ss;
    ss << mValue;

    return ss.str();
}

void SerializedNumber::setBool(bool value)
{
    mValue = (f64)value;
}

void SerializedNumber::setFloat(f32 value)
{
    mValue = (f64)value;
}

void SerializedNumber::setInt(s32 value)
{
    mValue = (f64)value;
}

void SerializedNumber::setString(const std::string &value)
{
    stringstream ss(value);
    ss >> mValue;
}


// SerializedObject class
// SerializedObject constructor.
SerializedObject::SerializedObject(const std::string &name, Serializable *object)
: SerializedAttribute(name, "object"), mObject(NULL)
{
    setObject(object);
}

// SerializedObject deconstructor.
SerializedObject::~SerializedObject()
{
    if(mObject != NULL)
      mObject->drop();
}

Serializable* SerializedObject::getObject()
{
    return mObject;
}

void SerializedObject::setObject(Serializable *object)
{
    if(mObject != NULL)
      mObject->drop();

    mObject = object;

    if(mObject != NULL)
      mObject->grab();
}


// SerializedPlane3d class
// SerializedPlane3d constructor (plane3df).
SerializedPlane3d::SerializedPlane3d(const std::string &name, const plane3df &value)
: SerializedAttribute(name, "plane3d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedPlane3d constructor (plane3di).
SerializedPlane3d::SerializedPlane3d(const std::string &name, const plane3di &value)
: SerializedAttribute(name, "plane3d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedPlane3d deconstructor.
SerializedPlane3d::~SerializedPlane3d()
{
}

std::string SerializedPlane3d::getString()
{
    SerializedVector3d normal("", mValue.Normal);

    stringstream ss;
    ss << "plane3d(" << normal.getString() << ", " << mValue.D << ")";

    return ss.str();
}

plane3df SerializedPlane3d::getPlane3df()
{
    return convert<f32, f64>(mValue);
}

plane3di SerializedPlane3d::getPlane3di()
{
    return convert<s32, f64>(mValue);
}

void SerializedPlane3d::setPlane3df(const plane3df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedPlane3d::setPlane3di(const plane3di &value)
{
    mValue = convert<f64, s32>(value);
}

void SerializedPlane3d::setString(const std::string &value)
{
    std::string typelessValue = removeStringFormatting(value, "plane3d");

    SerializedVector3d normal("", vector3df());
    normal.setString(typelessValue.substr(0, typelessValue.find(")")+1));

    stringstream D(typelessValue.substr(typelessValue.find(")")+1));

    plane3df plane;
    plane.Normal = normal.getVector3df();
    D >> plane.D;

    mValue = convert<f64, f32>(plane);
}


// SerializedQuaternion class
// SerializedQuaternion constructor.
SerializedQuaternion::SerializedQuaternion(const std::string &name, const quaternion &value)
: SerializedAttribute(name, "quaternion")
{
    mValue = value;
}

// SerializedQuaternion deconstructor.
SerializedQuaternion::~SerializedQuaternion()
{
}

std::string SerializedQuaternion::getString()
{
    stringstream ss;
    ss << "quaternion(" << mValue.X << ", " << mValue.Y << ", " << mValue.Z << ",  " << mValue.W << ")";

    return ss.str();
}

quaternion SerializedQuaternion::getQuaternion()
{
    return mValue;
}

void SerializedQuaternion::setQuaternion(const quaternion &value)
{
    mValue = value;
}

void SerializedQuaternion::setString(const std::string &value)
{
    // Remove formatting from the given string.
    stringstream ss(removeStringFormatting(value, "quaternion"));

    // Set the new values of the quaternion.
    ss >> mValue.X;
    ss >> mValue.Y;
    ss >> mValue.Z;
    ss >> mValue.W;
}


// SerializedRect class
// SerializedRect constructor.
SerializedRect::SerializedRect(const std::string &name, const rect<s32> &value)
: SerializedAttribute(name, "rect")
{
    mValue = value;
}

// SerializedRect deconstructor.
SerializedRect::~SerializedRect()
{
}

std::string SerializedRect::getString()
{
    SerializedVector2d UpperLeftCorner("", mValue.UpperLeftCorner);
    SerializedVector2d LowerRightCorner("", mValue.LowerRightCorner);

    stringstream ss;
    ss << "rect(" << UpperLeftCorner.getString() << ", " << LowerRightCorner.getString() << ")";

    return ss.str();
}

rect<s32> SerializedRect::getRect()
{
    return mValue;
}

void SerializedRect::setRect(const rect<s32> &value)
{
    mValue = value;
}

void SerializedRect::setString(const std::string &value)
{
    std::string typelessValue = removeStringFormatting(value, "rect");

    SerializedVector2d UpperLeftCorner("", vector2df());
    UpperLeftCorner.setString(typelessValue.substr(typelessValue.find(")")+1));

    SerializedVector2d LowerRightCorner("", vector2df());
    LowerRightCorner.setString(typelessValue.substr(0, typelessValue.find(")")+1));

    mValue.UpperLeftCorner = UpperLeftCorner.getVector2di();
    mValue.LowerRightCorner = LowerRightCorner.getVector2di();
}


// SerializedString class
// SerializedString constructor (std::string).
SerializedString::SerializedString(const std::string &name, const std::string &value)
: SerializedAttribute(name, "string")
{
    setString(value);
}

// SerializedString constructor (stringw).
SerializedString::SerializedString(const std::string &name, const stringw &value)
: SerializedAttribute(name, "string")
{
    mValue = value;
}

// SerializedString deconstructor.
SerializedString::~SerializedString()
{
}

std::string SerializedString::getString()
{
    return stringc(getStringW().c_str()).c_str();
}

stringw SerializedString::getStringW()
{
    return mValue;
}

void SerializedString::setString(const std::string &value)
{
    setStringW( value.c_str() );
}

void SerializedString::setStringW(const stringw &value)
{
    mValue = value;
}


// SerializedVector2d class
// SerializedVector2d constructor (vector2df).
SerializedVector2d::SerializedVector2d(const std::string &name, const vector2df &value)
: SerializedAttribute(name, "vector2d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedVector2d constructor (vector2di).
SerializedVector2d::SerializedVector2d(const std::string &name, const vector2di &value)
: SerializedAttribute(name, "vector2d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedVector2d constructor (vector2d<f64>).
SerializedVector2d::SerializedVector2d(const std::string &name, const vector2d<f64> &value)
: SerializedAttribute(name, "vector2d")
{
    mValue = value;
}

// SerializedVector2d deconstructor.
SerializedVector2d::~SerializedVector2d()
{
}

std::string SerializedVector2d::getString()
{
    stringstream ss;
    ss << "vector2d(" << mValue.X << ", " << mValue.Y << ")";

    return ss.str();
}

vector2df SerializedVector2d::getVector2df()
{
    return convert<f32, f64>(mValue);
}

vector2di SerializedVector2d::getVector2di()
{
    return convert<s32, f64>(mValue);
}

void SerializedVector2d::setString(const std::string &value)
{
    // Remove formatting from the given string.
    stringstream ss(removeStringFormatting(value, "vector2d"));

    // Set the new values of the vector2d.
    ss >> mValue.X;
    ss >> mValue.Y;
}

void SerializedVector2d::setVector2df(const vector2df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedVector2d::setVector2di(const vector2di &value)
{
    mValue = convert<f64, s32>(value);
}


// SerializedVector3d class
// SerializedVector3d constructor (vector3df).
SerializedVector3d::SerializedVector3d(const std::string &name, const vector3df &value)
: SerializedAttribute(name, "vector3d")
{
    mValue = convert<f64, f32>(value);
}

// SerializedVector3d constructor (vector3di).
SerializedVector3d::SerializedVector3d(const std::string &name, const vector3di &value)
: SerializedAttribute(name, "vector3d")
{
    mValue = convert<f64, s32>(value);
}

// SerializedVector3d constructor (vector3d<f64>).
SerializedVector3d::SerializedVector3d(const std::string &name, const vector3d<f64> &value)
: SerializedAttribute(name, "vector3d")
{
    mValue = value;
}

// SerializedVector3d deconstructor.
SerializedVector3d::~SerializedVector3d()
{
}

std::string SerializedVector3d::getString()
{
    stringstream ss;
    ss << "vector3d(" << mValue.X << ", " << mValue.Y << ", " << mValue.Z << ")";

    return ss.str();
}

vector3df SerializedVector3d::getVector3df()
{
    return convert<f32, f64>(mValue);
}

vector3di SerializedVector3d::getVector3di()
{
    return convert<s32, f64>(mValue);
}

void SerializedVector3d::setString(const std::string &value)
{
    // Remove formatting from the given string.
    stringstream ss(removeStringFormatting(value, "vector3d"));

    // Set the new values of the vector3d.
    ss >> mValue.X;
    ss >> mValue.Y;
    ss >> mValue.Z;
}

void SerializedVector3d::setVector3df(const vector3df &value)
{
    mValue = convert<f64, f32>(value);
}

void SerializedVector3d::setVector3di(const vector3di &value)
{
    mValue = convert<f64, s32>(value);
}

// End of File
